package com.org.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.org.DTO.PageDTO;
import com.org.DTO.SearchItemsDTO;
import com.org.clients.HttpClient;
import com.org.context.BaseContext;
import com.org.entity.CollectItems;
import com.org.entity.SearchItems;
import com.org.exception.BaseException;
import com.org.exception.ServerException;
import com.org.mapper.SearchItemsMapper;
import com.org.message.BaseMessage;
import com.org.properties.RedisKeyPropertis;
import com.org.service.SearchItemsService;
import com.org.vo.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Objects;

@Service
@Slf4j
@RequiredArgsConstructor
public class SearchItemsServiceImpl extends ServiceImpl<SearchItemsMapper, SearchItems> implements SearchItemsService {

    private final SearchItemsMapper searchItemsMapper;

    private final String BACKUP_SEARCH_ITEMS_URL = "http://localhost:8080/pc/backup/addSearchItems";

    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 分页查询所有失物招领信息
     * @param pageDTO
     * @return
     */
    @Override
    public PageResult findAllPage(PageDTO pageDTO) {
        //1.参数校验
        if(pageDTO.getRegionId() == null){
            throw new BaseException(BaseMessage.SELECT_ERROR);
        }

        //2.分页查询
        Page<SearchItems> page = lambdaQuery()
                .eq(SearchItems::getRegionId, pageDTO.getRegionId())
                .eq(pageDTO.getStatus() != null, SearchItems::getStatus, pageDTO.getStatus())
                .eq(pageDTO.getIsMe() == 0, SearchItems::getUserId, BaseContext.getCurrentId())
                .page(new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize()));
        return new PageResult(page.getTotal(), page.getRecords());
    }

    /**
     * 添加失物招领信息
     * @param searchItemsDTO
     */
    @Override
    public void addSearchItems(SearchItemsDTO searchItemsDTO) {
        //1.号码格式校验
        if(!searchItemsDTO.getPhone().matches("^1[3-9]\\d{9}$")){
           throw new BaseException(BaseMessage.PHONE_ERROR);
        }
        //2.构建对象
        SearchItems searchItems = new SearchItems();
        BeanUtils.copyProperties(searchItemsDTO,searchItems);
        searchItems.setCreateTime(LocalDateTime.now());
        searchItems.setUpdateTime(LocalDateTime.now());
        searchItems.setUserId(BaseContext.getCurrentId());
        //3.添加
        save(searchItems);
    }

    /**
     * 根据id查询失物招领信息
     * @param id
     * @return
     */
    @Override
    public SearchItems findSearchItemsById(Long id) {
        //1.参数校验
        verifyId(id);
        //2.查询
        return searchItemsMapper.selectById(id);
    }

    /**
     * 修改失物招领信息
     * @param searchItemsDTO
     */
    @Override
    public void updateSearchItems(SearchItemsDTO searchItemsDTO) {
        //1.参数校验
        verifyId(searchItemsDTO.getId());
        //1.2、号码格式校验
        if(searchItemsDTO.getPhone() != null && !searchItemsDTO.getPhone().isEmpty()){
            if(!searchItemsDTO.getPhone().matches("^1[3-9]\\d{9}$")){
                throw new BaseException(BaseMessage.PHONE_ERROR);
            }
        }
        //2.构建对象
        SearchItems searchItems = new SearchItems();
        BeanUtils.copyProperties(searchItemsDTO,searchItems);
        searchItems.setUpdateTime(LocalDateTime.now());
        //3.修改
        //3.1、构建SQL
        LambdaUpdateWrapper<SearchItems> uw = new LambdaUpdateWrapper<SearchItems>()
                .set(searchItems.getItemName() != null && !searchItems.getItemName().isEmpty(),
                        SearchItems::getItemName, searchItems.getItemName())
                .set(searchItems.getPhone() != null && !searchItems.getPhone().isEmpty(),
                        SearchItems::getPhone, searchItems.getPhone())
                .set(searchItems.getDescribe() != null && !searchItems.getDescribe().isEmpty(),
                        SearchItems::getDescribe, searchItems.getDescribe())
                .set(searchItems.getImage() != null && !searchItems.getImage().isEmpty(),
                        SearchItems::getImage, searchItems.getImage())
                .set(searchItems.getRegionId() != null,
                        SearchItems::getRegionId, searchItems.getRegionId())
                .set(searchItems.getStatus() != null, SearchItems::getStatus, searchItems.getStatus())
                .set(searchItems.getUserId() != null,
                        SearchItems::getUserId, searchItems.getUserId())
                .set(searchItems.getDropStorage() != null && !searchItems.getDropStorage().isEmpty(),
                        SearchItems::getDropStorage, searchItems.getDropStorage())
                .set(searchItems.getCreateTime() != null,
                        SearchItems::getCreateTime, searchItems.getCreateTime())
                .eq(SearchItems::getId, searchItemsDTO.getId());

        //2.1、判断图片是否需要修改
        if(searchItems.getImage() != null && !searchItems.getImage().isEmpty()){
            //2.1.1、查询旧数据
            SearchItems oldSearchItems = searchItemsMapper.selectById(searchItems.getId());
            //2.1.2、修改数据并拿到执行结果
            boolean ifUpdate = update(uw);
            if(ifUpdate){
                //3、删除redis中的旧图片
                stringRedisTemplate.opsForSet().remove(RedisKeyPropertis.REDIS_KEY_UP_USE, oldSearchItems.getImage());
                //4、添加新图片到Redis
                stringRedisTemplate.opsForSet().add(RedisKeyPropertis.REDIS_KEY_UP_USE, searchItems.getImage());
            }
        }else{
            //2.2、修改数据
            update(uw);
        }

    }

    /**
     * 删除失物招领信息
     * @param id
     */
    @Override
    @Transactional
    public void deleteSearchItemsById(Long id) {
        //1.参数校验
        verifyId(id);
        //2.查询数据，用于备份
        SearchItems searchItems = searchItemsMapper.selectById(id);
        if(searchItems == null){
            throw new BaseException(BaseMessage.DELETE_ERROR);
        }
        //3.删除
        searchItemsMapper.deleteById(id);
        log.info("删除成功,删除的寻物启事ID为{}", id);
        //4.备份
        //4.1、遍历searchItems，构建HashMap
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("searchItemsId", searchItems.getId().toString());
        paramMap.put("itemName", searchItems.getItemName());
        paramMap.put("phone", searchItems.getPhone());
        paramMap.put("describe", searchItems.getDescribe());
        paramMap.put("image", searchItems.getImage());
        paramMap.put("regionId", searchItems.getRegionId().toString());
        paramMap.put("status", "2");
        paramMap.put("dropStorage", searchItems.getDropStorage());
        paramMap.put("userId", searchItems.getUserId().toString());
        paramMap.put("operatorId", BaseContext.getCurrentId().toString());
        try {
            HttpClient.doPost4Json(BACKUP_SEARCH_ITEMS_URL, paramMap, BaseContext.getThreadLocalToken());
        } catch (IOException e) {
            log.error("备份寻物启事请求失败,异常信息为", e);
            throw new ServerException(BaseMessage.SERVER_ERROR);
        }
    }

    /**
     * 修改寻物启事状态
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Long status) {
        //1.参数校验
        verifyId(id);
        verifyId(status);
        //2.修改
        LambdaUpdateWrapper<SearchItems> uw = new LambdaUpdateWrapper<SearchItems>()
                .set(SearchItems::getStatus, status)
                .eq(SearchItems::getId, id);
        update(uw);
    }

    /**
     * 参数校验
     * @param id
     */
    private static void verifyId(Long id) {
        if(id == null){
            throw new BaseException(BaseMessage.INVALID_MESSAGE);
        }
    }
}
